/*
 ============================================================================
 Name        : tp0.c
 Author      : Ezequiel Aceto
 Version     : 0.0.1
 Copyright   : 2C-2011
 Description : [6620] Organización de Computadoras
 ============================================================================
 */

#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>
#include <math.h>
#include <string.h>
#include "merger.h"

#define MAXLINE 1024

void usage(char* progname) {
	fprintf(stdout, "Usage:\n");

	fprintf(stdout, "Usage: join [OPTION]... FILE1 FILE2\n");

	fprintf(
			stdout,
			"For each pair of input lines with identical join fields, write a line to\n");
	fprintf(
			stdout,
			"standard output. The default join field is the first, delimited\n");
	fprintf(
			stdout,
			"by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n");
	fprintf(
			stdout,
			"\t-i, --ignore-case ignore differences in case when comparing fields\n");
	fprintf(stdout, "\t-h, --help display this help and exit\n");
	fprintf(stdout, "\t-v, --version output version information and exit\n\n");

	fprintf(stdout,
			"Important: FILE1 and FILE2 must be sorted on the join fields.\n");
	fprintf(stdout, "E.g., use `sort -k 1b,1' if `join' has no options.\n");
	fprintf(stdout,
			"Note, comparisons honor the rules specified by `LC_COLLATE'.\n");
	fprintf(stdout,
			"If the input is not sorted and some lines cannot be joined, a\n");
	fprintf(stdout, "warning message will be given.\n");

	fprintf(stdout,"EJEMPLO DE USO: ./tp0 -i <pathArchivo1> <pathArchivo2>\n");
	fprintf(stdout,"Donde \"pathArchivoX\" va la ruta del archivoX.\n");
}

void version() {
	fprintf(stdout, "TP0 :: Join\n");
	fprintf(stdout, "66.20 - Organización de Computadoras\n");
	fprintf(stdout, "2do Cuat. 2011\n");
	fprintf(stdout, "---------------------------------------------\n");
	fprintf(stdout, "Developed by:\n");
	fprintf(stdout, "\tRamiro Gosendet[86397]\n");
	fprintf(stdout, "\tNicolas Di Tomaso[88408]\n");
	fprintf(stdout, "\tEzequiel Leonardo Aceto [84316]\n");
	fprintf(stdout, "---------------------------------------------\n");
	fprintf(stdout, "Report bugs to: ezequiel.aceto (at) gmail.com\n");
}

int main(int argc, char** argv) {

	int ch;
	char tempFileCreated = 0;

	static struct option longopts[] = { { "version", no_argument, NULL, 'v' }, {
			"help", no_argument, NULL, 'h' }, { "ignore-case", no_argument,
			NULL, 'i' }, { NULL, 0, NULL, 0 } };

	char ignoreCase = 0; // 0 = CASE SENSITIVE - 1 = IGNORE CASE
	while ((ch = getopt_long(argc, argv, "ivh", longopts, NULL)) != -1) {

		switch (ch) {
		case 'h':
			usage(argv[0]);
			exit(0);
			break;
		case 'v':
			version();
			exit(0);
			break;
		case 'i':
			ignoreCase = 1;
			break;
		default:
			fprintf(stdout, "parametro desconocido\n");
			break;
		}

	}

	// validacion de cantidad de parametros de entrada
	if (ignoreCase == 1 && argc != 4) {
		usage(argv[0]);
		exit(1);
	}
	if (ignoreCase == 0 && argc != 3) {
		usage(argv[0]);
		exit(1);
	}

	FILE* pFile1 = NULL, *pFile2 = NULL;

	char* szFromSTDIn = "-";

	if (optind < argc) {
		// get first file

		if (strcmp(szFromSTDIn, argv[optind]) == 0) {
			pFile1 = stdin;
		} else {
			if ((pFile1 = fopen(argv[optind], "r")) == NULL) {
				fprintf(stderr, "Cannot open file 1.\n");
				exit(2);
			}
		}

		optind++;

		// get second file
		if (strcmp(szFromSTDIn, argv[optind]) == 0) {
			pFile2 = stdin;
		} else {
			if ((pFile2 = fopen(argv[optind], "r")) == NULL) {
				fprintf(stderr, "Cannot open file 2.\n");
				exit(3);
			}
		}

		if (pFile1 == stdin && pFile2 == stdin) {
			fprintf(stderr, "Both files cannot be taken from stdin.\n");
			exit(4);
		}
	} else {
		fprintf(stderr, "Input files missing.\n");
		exit(5);
	}

	if (pFile1 == stdin) {
		//obtengo el archivo hasta detectar una linea vacia (doble enter)
		if ((pFile1 = fopen(".jointemp", "w+")) == NULL) {
			fprintf(stderr, "Cannot open file 1.\n");
		} else {
			char line[1024];
			while (fgets(line, sizeof line, stdin) != NULL) {
				if (line[0] == '\n') {
					break;
				}
				// write in file
				fprintf(pFile1, "%s", line);
			}
			fseek(pFile1, 0, SEEK_SET);
			tempFileCreated = 1;
		}
	} else if (pFile2 == stdin) {
		//obtengo el archivo hasta detectar una linea vacia (doble enter)
		if ((pFile2 = fopen(".jointemp", "w+")) == NULL) {
			fprintf(stderr, "Cannot open file 1.\n");
		} else {
			char line[1024];
			while (fgets(line, sizeof line, stdin) != NULL) {
				if (line[0] == '\n') {
					break;
				}
				// write in file
				fprintf(pFile2, "%s", line);
			}
			fseek(pFile2, 0, SEEK_SET);
			tempFileCreated = 1;
		}
	}

	if (pFile1 == NULL) {
		fprintf(stderr, "File 1 is null\n");
		exit(6);
	}

	if (pFile2 == NULL) {
		fprintf(stderr, "File 2 is null.\n");
		exit(6);
	}

	merge(pFile1, pFile2, ignoreCase);

	if (pFile1 != stdin
		)
		fclose(pFile1);
	if (pFile2 != stdin
		)
		fclose(pFile2);

	if (tempFileCreated == 1) {
		// remove temp filed
		remove(".jointemp");
	}
	return EXIT_SUCCESS;
}
